"""
Flask综合示例 - 整合所有工具包功能的完整应用
包含用户管理、文章系统、评论功能、文件上传等完整业务场景
"""

from flask import Flask, request, jsonify, g, send_file
import os
import sys
import time
import tempfile
from datetime import datetime, timedelta
from typing import Dict, Any, Optional, List
from functools import wraps
from sqlalchemy import Column, Integer, String, Text, DateTime, Boolean, ForeignKey, LargeBinary
from sqlalchemy.orm import relationship

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from python_backend_toolkit.auth import (
    JWTAuth, PasswordManager, RoleManager, Permission
)
from python_backend_toolkit.cache import CacheManager, MemoryCache, RedisCache
from python_backend_toolkit.database import (
    Base, BaseModel, DatabaseSession, get_db,
    BaseRepository, BaseService
)
from python_backend_toolkit.logging import get_logger, setup_logging
from python_backend_toolkit.http_client import HTTPClient
from python_backend_toolkit.utils import (
    generate_uuid, generate_random_string, validate_email,
    sanitize_filename, format_datetime, mask_sensitive_data,
    calculate_file_hash
)
from python_backend_toolkit.api.responses import (
    SuccessResponse, ErrorResponse, PaginatedResponse,
    CreatedResponse, UpdatedResponse, DeletedResponse
)
from python_backend_toolkit.api.exceptions import (
    ValidationError, NotFoundError, UnauthorizedError,
    ForbiddenError, ConflictError
)


# ========================================================================
# 数据库模型
# ========================================================================

class User(BaseModel):
    """用户模型"""
    __tablename__ = 'users'
    
    username = Column(String(50), unique=True, nullable=False)
    email = Column(String(200), unique=True, nullable=False)
    password_hash = Column(String(255), nullable=False)
    first_name = Column(String(50))
    last_name = Column(String(50))
    avatar_url = Column(String(500))
    bio = Column(Text)
    role = Column(String(20), default='user')
    is_verified = Column(Boolean, default=False)
    last_login = Column(DateTime)
    
    # 关系
    articles = relationship("Article", back_populates="author", lazy="dynamic")
    comments = relationship("Comment", back_populates="author", lazy="dynamic")
    files = relationship("FileUpload", back_populates="uploader", lazy="dynamic")
    
    def to_dict(self, include_sensitive=False):
        """转换为字典"""
        data = super().to_dict()
        if not include_sensitive:
            data.pop('password_hash', None)
        return data


class Category(BaseModel):
    """分类模型"""
    __tablename__ = 'categories'
    
    name = Column(String(100), nullable=False, unique=True)
    description = Column(Text)
    color = Column(String(7), default='#007bff')  # 颜色代码
    
    # 关系
    articles = relationship("Article", back_populates="category", lazy="dynamic")


class Article(BaseModel):
    """文章模型"""
    __tablename__ = 'articles'
    
    title = Column(String(200), nullable=False)
    content = Column(Text, nullable=False)
    summary = Column(String(500))
    author_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    category_id = Column(Integer, ForeignKey('categories.id'), nullable=False)
    published_at = Column(DateTime)
    view_count = Column(Integer, default=0)
    like_count = Column(Integer, default=0)
    featured_image_url = Column(String(500))
    tags = Column(String(500))  # 逗号分隔的标签
    
    # 关系
    author = relationship("User", back_populates="articles")
    category = relationship("Category", back_populates="articles")
    comments = relationship("Comment", back_populates="article", lazy="dynamic")


class Comment(BaseModel):
    """评论模型"""
    __tablename__ = 'comments'
    
    content = Column(Text, nullable=False)
    author_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    article_id = Column(Integer, ForeignKey('articles.id'), nullable=False)
    parent_id = Column(Integer, ForeignKey('comments.id'))  # 回复评论
    
    # 关系
    author = relationship("User", back_populates="comments")
    article = relationship("Article", back_populates="comments")
    parent = relationship("Comment", remote_side="Comment.id")


class FileUpload(BaseModel):
    """文件上传模型"""
    __tablename__ = 'file_uploads'
    
    filename = Column(String(255), nullable=False)
    original_filename = Column(String(255), nullable=False)
    file_size = Column(Integer, nullable=False)
    file_hash = Column(String(64), nullable=False)
    mime_type = Column(String(100))
    file_path = Column(String(500), nullable=False)
    uploader_id = Column(Integer, ForeignKey('users.id'), nullable=False)
    
    # 关系
    uploader = relationship("User", back_populates="files")


# ========================================================================
# 仓储层
# ========================================================================

class UserRepository(BaseRepository[User]):
    """用户仓储"""
    
    def find_by_username(self, username: str) -> Optional[User]:
        return self.session.query(User).filter(User.username == username).first()
    
    def find_by_email(self, email: str) -> Optional[User]:
        return self.session.query(User).filter(User.email == email).first()
    
    def find_by_role(self, role: str) -> List[User]:
        return self.session.query(User).filter(User.role == role).all()


class ArticleRepository(BaseRepository[Article]):
    """文章仓储"""
    
    def find_published(self, page: int = 1, size: int = 10) -> Dict[str, Any]:
        query = self.session.query(Article).filter(
            Article.published_at.isnot(None),
            Article.published_at <= datetime.utcnow()
        ).order_by(Article.published_at.desc())
        return self._paginate_query(query, page, size)
    
    def find_by_author(self, author_id: int, page: int = 1, size: int = 10) -> Dict[str, Any]:
        query = self.session.query(Article).filter(
            Article.author_id == author_id
        ).order_by(Article.created_at.desc())
        return self._paginate_query(query, page, size)
    
    def search_by_title(self, keyword: str, page: int = 1, size: int = 10) -> Dict[str, Any]:
        query = self.session.query(Article).filter(
            Article.title.contains(keyword)
        ).order_by(Article.created_at.desc())
        return self._paginate_query(query, page, size)


# ========================================================================
# 服务层
# ========================================================================

class UserService(BaseService[User]):
    """用户服务"""
    
    def __init__(self, repository: UserRepository, password_manager: PasswordManager):
        super().__init__(repository)
        self.repository = repository
        self.password_manager = password_manager
        self.logger = get_logger("UserService")
    
    def create_user(self, username: str, email: str, password: str, 
                   first_name: str = None, last_name: str = None) -> User:
        """创建用户"""
        # 验证用户名和邮箱唯一性
        if self.repository.find_by_username(username):
            raise ConflictError(f"Username '{username}' already exists")
        
        if self.repository.find_by_email(email):
            raise ConflictError(f"Email '{email}' already exists")
        
        # 验证邮箱格式
        if not validate_email(email):
            raise ValidationError("Invalid email format")
        
        # 加密密码
        password_hash = self.password_manager.hash_password(password)
        
        user = User(
            username=username,
            email=email,
            password_hash=password_hash,
            first_name=first_name,
            last_name=last_name
        )
        
        created_user = self.repository.create(user)
        
        self.logger.info(
            "User created successfully",
            user_id=created_user.id,
            username=username,
            email=mask_sensitive_data({"email": email}, ["email"])["email"]
        )
        
        return created_user
    
    def authenticate_user(self, username: str, password: str) -> Optional[User]:
        """用户认证"""
        user = self.repository.find_by_username(username)
        if not user:
            return None
        
        if not self.password_manager.verify_password(password, user.password_hash):
            return None
        
        # 更新最后登录时间
        user.last_login = datetime.utcnow()
        self.repository.update(user)
        
        self.logger.info(
            "User authenticated successfully",
            user_id=user.id,
            username=username
        )
        
        return user
    
    def change_password(self, user_id: int, old_password: str, new_password: str) -> bool:
        """修改密码"""
        user = self.repository.get_by_id(user_id)
        if not user:
            return False
        
        if not self.password_manager.verify_password(old_password, user.password_hash):
            raise ValidationError("Current password is incorrect")
        
        user.password_hash = self.password_manager.hash_password(new_password)
        self.repository.update(user)
        
        self.logger.info(
            "Password changed successfully",
            user_id=user_id
        )
        
        return True


class ArticleService(BaseService[Article]):
    """文章服务"""
    
    def __init__(self, repository: ArticleRepository, user_repository: UserRepository):
        super().__init__(repository)
        self.repository = repository
        self.user_repository = user_repository
        self.logger = get_logger("ArticleService")
    
    def create_article(self, title: str, content: str, author_id: int,
                      category_id: int, summary: str = None, tags: str = None) -> Article:
        """创建文章"""
        # 验证作者存在
        author = self.user_repository.get_by_id(author_id)
        if not author:
            raise NotFoundError("Author not found")
        
        article = Article(
            title=title,
            content=content,
            summary=summary or content[:200] + "..." if len(content) > 200 else content,
            author_id=author_id,
            category_id=category_id,
            tags=tags
        )
        
        created_article = self.repository.create(article)
        
        self.logger.info(
            "Article created successfully",
            article_id=created_article.id,
            title=title,
            author_id=author_id
        )
        
        return created_article
    
    def publish_article(self, article_id: int, user_id: int) -> bool:
        """发布文章"""
        article = self.repository.get_by_id(article_id)
        if not article:
            return False
        
        # 检查权限（只有作者或管理员可以发布）
        if article.author_id != user_id:
            user = self.user_repository.get_by_id(user_id)
            if not user or user.role != 'admin':
                raise ForbiddenError("Permission denied")
        
        article.published_at = datetime.utcnow()
        self.repository.update(article)
        
        self.logger.info(
            "Article published successfully",
            article_id=article_id,
            published_by=user_id
        )
        
        return True


# ========================================================================
# 认证装饰器
# ========================================================================

def require_auth(f):
    """需要认证的装饰器"""
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not hasattr(g, 'current_user') or not g.current_user:
            raise UnauthorizedError("Authentication required")
        return f(*args, **kwargs)
    return decorated_function


def require_role(role: str):
    """需要特定角色的装饰器"""
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if not hasattr(g, 'current_user') or not g.current_user:
                raise UnauthorizedError("Authentication required")
            
            if g.current_user.role != role and g.current_user.role != 'admin':
                raise ForbiddenError("Insufficient permissions")
            
            return f(*args, **kwargs)
        return decorated_function
    return decorator


def create_comprehensive_app() -> Flask:
    """创建综合示例Flask应用"""
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'comprehensive-demo-secret'
    app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16MB max file size
    
    # 初始化日志
    setup_logging()
    logger = get_logger("ComprehensiveApp")
    
    # 初始化数据库
    db_session = DatabaseSession(
        database_url="sqlite:///flask_comprehensive_demo.db",
        echo=False
    )
    db_session.create_tables()
    
    # 初始化缓存
    cache_manager = CacheManager()
    cache_manager.add_cache("default", MemoryCache())
    
    # 初始化认证
    jwt_auth = JWTAuth(secret_key=app.config['SECRET_KEY'])
    password_manager = PasswordManager()
    role_manager = RoleManager()
    
    # 初始化HTTP客户端
    http_client = HTTPClient()
    
    # 初始化服务
    def get_services():
        session = db_session.get_session()
        
        # 仓储
        user_repo = UserRepository(User, session)
        article_repo = ArticleRepository(Article, session)
        
        # 服务
        user_service = UserService(user_repo, password_manager)
        article_service = ArticleService(article_repo, user_repo)
        
        return {
            'user_service': user_service,
            'article_service': article_service,
            'session': session
        }
    
    # ========================================================================
    # 中间件
    # ========================================================================
    
    @app.before_request
    def before_request():
        """请求前处理"""
        g.request_id = generate_uuid()
        g.start_time = time.time()
        g.services = get_services()
        g.current_user = None
        
        # 处理认证
        auth_header = request.headers.get('Authorization')
        if auth_header and auth_header.startswith('Bearer '):
            token = auth_header.split(' ')[1]
            try:
                payload = jwt_auth.decode_token(token)
                user_id = payload.get('user_id')
                if user_id:
                    g.current_user = g.services['user_service'].get_by_id(user_id)
            except Exception as e:
                logger.warning("Invalid token", token_error=str(e))
        
        # 请求日志
        logger.info(
            "Request started",
            request_id=g.request_id,
            method=request.method,
            path=request.path,
            user_id=g.current_user.id if g.current_user else None
        )
    
    @app.after_request
    def after_request(response):
        """请求后处理"""
        duration = time.time() - g.start_time
        
        logger.info(
            "Request completed",
            request_id=g.request_id,
            status_code=response.status_code,
            duration=duration
        )
        
        # 关闭数据库会话
        if hasattr(g, 'services') and 'session' in g.services:
            g.services['session'].close()
        
        return response
    
    @app.errorhandler(ValidationError)
    def handle_validation_error(e):
        return jsonify(ErrorResponse.create(message=str(e)).dict()), 400
    
    @app.errorhandler(NotFoundError)
    def handle_not_found_error(e):
        return jsonify(ErrorResponse.create(message=str(e)).dict()), 404
    
    @app.errorhandler(UnauthorizedError)
    def handle_unauthorized_error(e):
        return jsonify(ErrorResponse.create(message=str(e)).dict()), 401
    
    @app.errorhandler(ForbiddenError)
    def handle_forbidden_error(e):
        return jsonify(ErrorResponse.create(message=str(e)).dict()), 403
    
    @app.errorhandler(ConflictError)
    def handle_conflict_error(e):
        return jsonify(ErrorResponse.create(message=str(e)).dict()), 409
    
    # ========================================================================
    # 认证API
    # ========================================================================
    
    @app.route('/auth/register', methods=['POST'])
    def register():
        """用户注册"""
        try:
            data = request.get_json()
            
            username = data.get('username', '').strip()
            email = data.get('email', '').strip()
            password = data.get('password', '')
            first_name = data.get('first_name', '').strip()
            last_name = data.get('last_name', '').strip()
            
            if not all([username, email, password]):
                raise ValidationError("Username, email, and password are required")
            
            user = g.services['user_service'].create_user(
                username=username,
                email=email,
                password=password,
                first_name=first_name or None,
                last_name=last_name or None
            )
            
            # 生成JWT令牌
            token = jwt_auth.generate_token({
                'user_id': user.id,
                'username': user.username,
                'role': user.role
            })
            
            response = CreatedResponse.create(
                data={
                    "user": user.to_dict(),
                    "token": token
                },
                message="User registered successfully"
            )
            return jsonify(response.dict()), 201
            
        except (ValidationError, ConflictError) as e:
            raise
        except Exception as e:
            logger.error("Registration error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Registration failed"
            ).dict()), 500
    
    @app.route('/auth/login', methods=['POST'])
    def login():
        """用户登录"""
        try:
            data = request.get_json()
            
            username = data.get('username', '').strip()
            password = data.get('password', '')
            
            if not all([username, password]):
                raise ValidationError("Username and password are required")
            
            user = g.services['user_service'].authenticate_user(username, password)
            if not user:
                raise UnauthorizedError("Invalid username or password")
            
            # 生成JWT令牌
            token = jwt_auth.generate_token({
                'user_id': user.id,
                'username': user.username,
                'role': user.role
            })
            
            response = SuccessResponse.create(
                data={
                    "user": user.to_dict(),
                    "token": token
                },
                message="Login successful"
            )
            return jsonify(response.dict())
            
        except (ValidationError, UnauthorizedError) as e:
            raise
        except Exception as e:
            logger.error("Login error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Login failed"
            ).dict()), 500
    
    @app.route('/auth/me', methods=['GET'])
    @require_auth
    def get_current_user():
        """获取当前用户信息"""
        response = SuccessResponse.create(
            data={"user": g.current_user.to_dict()},
            message="User information retrieved successfully"
        )
        return jsonify(response.dict())
    
    @app.route('/auth/change-password', methods=['POST'])
    @require_auth
    def change_password():
        """修改密码"""
        try:
            data = request.get_json()
            
            old_password = data.get('old_password', '')
            new_password = data.get('new_password', '')
            
            if not all([old_password, new_password]):
                raise ValidationError("Old password and new password are required")
            
            success = g.services['user_service'].change_password(
                g.current_user.id, old_password, new_password
            )
            
            if not success:
                raise ValidationError("Failed to change password")
            
            response = SuccessResponse.create(
                message="Password changed successfully"
            )
            return jsonify(response.dict())
            
        except ValidationError as e:
            raise
        except Exception as e:
            logger.error("Change password error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to change password"
            ).dict()), 500
    
    # ========================================================================
    # 用户管理API
    # ========================================================================
    
    @app.route('/users', methods=['GET'])
    @require_role('admin')
    def list_users():
        """获取用户列表（管理员）"""
        try:
            page = int(request.args.get('page', 1))
            size = min(int(request.args.get('size', 10)), 50)
            
            result = g.services['user_service'].get_paginated(page, size)
            users = [user.to_dict() for user in result['items']]
            
            response = PaginatedResponse.create(
                data=users,
                page=result['page'],
                size=result['size'],
                total=result['total'],
                pages=result['pages'],
                message="Users retrieved successfully"
            )
            return jsonify(response.dict())
            
        except Exception as e:
            logger.error("List users error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to retrieve users"
            ).dict()), 500
    
    @app.route('/users/<int:user_id>', methods=['GET'])
    @require_auth
    def get_user(user_id: int):
        """获取用户详情"""
        try:
            # 用户只能查看自己的详情，管理员可以查看所有用户
            if g.current_user.id != user_id and g.current_user.role != 'admin':
                raise ForbiddenError("Permission denied")
            
            user = g.services['user_service'].get_by_id(user_id)
            if not user:
                raise NotFoundError("User not found")
            
            response = SuccessResponse.create(
                data={"user": user.to_dict()},
                message="User retrieved successfully"
            )
            return jsonify(response.dict())
            
        except (NotFoundError, ForbiddenError) as e:
            raise
        except Exception as e:
            logger.error("Get user error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to retrieve user"
            ).dict()), 500
    
    # ========================================================================
    # 文章管理API
    # ========================================================================
    
    @app.route('/articles', methods=['GET'])
    def list_articles():
        """获取文章列表"""
        try:
            page = int(request.args.get('page', 1))
            size = min(int(request.args.get('size', 10)), 50)
            published_only = request.args.get('published_only', 'true').lower() == 'true'
            author_id = request.args.get('author_id')
            search = request.args.get('search', '').strip()
            
            if search:
                result = g.services['article_service'].repository.search_by_title(search, page, size)
            elif author_id:
                result = g.services['article_service'].repository.find_by_author(int(author_id), page, size)
            elif published_only:
                result = g.services['article_service'].repository.find_published(page, size)
            else:
                result = g.services['article_service'].get_paginated(page, size)
            
            articles = [article.to_dict() for article in result['items']]
            
            response = PaginatedResponse.create(
                data=articles,
                page=result['page'],
                size=result['size'],
                total=result['total'],
                pages=result['pages'],
                message="Articles retrieved successfully"
            )
            return jsonify(response.dict())
            
        except Exception as e:
            logger.error("List articles error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to retrieve articles"
            ).dict()), 500
    
    @app.route('/articles', methods=['POST'])
    @require_auth
    def create_article():
        """创建文章"""
        try:
            data = request.get_json()
            
            title = data.get('title', '').strip()
            content = data.get('content', '').strip()
            category_id = data.get('category_id')
            summary = data.get('summary', '').strip()
            tags = data.get('tags', '').strip()
            
            if not all([title, content, category_id]):
                raise ValidationError("Title, content, and category_id are required")
            
            article = g.services['article_service'].create_article(
                title=title,
                content=content,
                author_id=g.current_user.id,
                category_id=category_id,
                summary=summary or None,
                tags=tags or None
            )
            
            response = CreatedResponse.create(
                data={"article": article.to_dict()},
                message="Article created successfully"
            )
            return jsonify(response.dict()), 201
            
        except (ValidationError, NotFoundError) as e:
            raise
        except Exception as e:
            logger.error("Create article error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to create article"
            ).dict()), 500
    
    @app.route('/articles/<int:article_id>', methods=['GET'])
    def get_article(article_id: int):
        """获取文章详情"""
        try:
            article = g.services['article_service'].get_by_id(article_id)
            if not article:
                raise NotFoundError("Article not found")
            
            # 增加浏览量
            article.view_count += 1
            g.services['article_service'].update(article)
            
            response = SuccessResponse.create(
                data={"article": article.to_dict()},
                message="Article retrieved successfully"
            )
            return jsonify(response.dict())
            
        except NotFoundError as e:
            raise
        except Exception as e:
            logger.error("Get article error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to retrieve article"
            ).dict()), 500
    
    @app.route('/articles/<int:article_id>/publish', methods=['POST'])
    @require_auth
    def publish_article(article_id: int):
        """发布文章"""
        try:
            success = g.services['article_service'].publish_article(article_id, g.current_user.id)
            
            if not success:
                raise NotFoundError("Article not found")
            
            response = SuccessResponse.create(
                message="Article published successfully"
            )
            return jsonify(response.dict())
            
        except (NotFoundError, ForbiddenError) as e:
            raise
        except Exception as e:
            logger.error("Publish article error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to publish article"
            ).dict()), 500
    
    # ========================================================================
    # 文件上传API
    # ========================================================================
    
    @app.route('/files/upload', methods=['POST'])
    @require_auth
    def upload_file():
        """文件上传"""
        try:
            if 'file' not in request.files:
                raise ValidationError("No file provided")
            
            file = request.files['file']
            if file.filename == '':
                raise ValidationError("No file selected")
            
            # 读取文件数据
            file_data = file.read()
            
            # 验证文件大小
            if len(file_data) > app.config['MAX_CONTENT_LENGTH']:
                raise ValidationError("File too large")
            
            # 清理文件名
            safe_filename = sanitize_filename(file.filename)
            
            # 生成唯一文件名
            file_id = generate_uuid()
            extension = os.path.splitext(safe_filename)[1]
            unique_filename = f"{file_id}{extension}"
            
            # 计算文件哈希
            file_hash = calculate_file_hash(file_data)
            
            # 保存文件
            upload_dir = os.path.join(tempfile.gettempdir(), 'uploads')
            os.makedirs(upload_dir, exist_ok=True)
            file_path = os.path.join(upload_dir, unique_filename)
            
            with open(file_path, 'wb') as f:
                f.write(file_data)
            
            # 保存文件信息到数据库
            file_upload = FileUpload(
                filename=unique_filename,
                original_filename=file.filename,
                file_size=len(file_data),
                file_hash=file_hash,
                mime_type=file.content_type,
                file_path=file_path,
                uploader_id=g.current_user.id
            )
            
            session = g.services['session']
            session.add(file_upload)
            session.commit()
            
            response = CreatedResponse.create(
                data={
                    "file": {
                        "id": file_upload.id,
                        "filename": file_upload.filename,
                        "original_filename": file_upload.original_filename,
                        "file_size": file_upload.file_size,
                        "mime_type": file_upload.mime_type,
                        "upload_url": f"/files/{file_upload.id}/download"
                    }
                },
                message="File uploaded successfully"
            )
            return jsonify(response.dict()), 201
            
        except ValidationError as e:
            raise
        except Exception as e:
            logger.error("File upload error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to upload file"
            ).dict()), 500
    
    @app.route('/files/<int:file_id>/download', methods=['GET'])
    def download_file(file_id: int):
        """文件下载"""
        try:
            session = g.services['session']
            file_upload = session.query(FileUpload).filter(FileUpload.id == file_id).first()
            
            if not file_upload:
                raise NotFoundError("File not found")
            
            if not os.path.exists(file_upload.file_path):
                raise NotFoundError("File not found on disk")
            
            return send_file(
                file_upload.file_path,
                as_attachment=True,
                download_name=file_upload.original_filename,
                mimetype=file_upload.mime_type
            )
            
        except NotFoundError as e:
            raise
        except Exception as e:
            logger.error("File download error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to download file"
            ).dict()), 500
    
    # ========================================================================
    # 缓存示例API
    # ========================================================================
    
    @app.route('/cache/test', methods=['POST'])
    @require_auth
    def test_cache():
        """测试缓存功能"""
        try:
            data = request.get_json() or {}
            key = data.get('key', 'test_key')
            value = data.get('value', 'test_value')
            ttl = data.get('ttl', 300)
            
            cache = cache_manager.get_cache("default")
            
            # 设置缓存
            cache.set(key, value, ttl)
            
            # 获取缓存
            cached_value = cache.get(key)
            
            response = SuccessResponse.create(
                data={
                    "key": key,
                    "original_value": value,
                    "cached_value": cached_value,
                    "ttl": ttl,
                    "cache_hit": cached_value is not None
                },
                message="Cache test completed"
            )
            return jsonify(response.dict())
            
        except Exception as e:
            logger.error("Cache test error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Cache test failed"
            ).dict()), 500
    
    # ========================================================================
    # 应用信息
    # ========================================================================
    
    @app.route('/health', methods=['GET'])
    def health_check():
        """健康检查"""
        try:
            # 检查数据库连接
            db_session.check_connection()
            
            return jsonify({
                "status": "healthy",
                "timestamp": datetime.utcnow().isoformat(),
                "database": "connected",
                "cache": "active",
                "auth": "active"
            })
        except Exception as e:
            return jsonify({
                "status": "unhealthy",
                "timestamp": datetime.utcnow().isoformat(),
                "error": str(e)
            }), 500
    
    @app.route('/info', methods=['GET'])
    def app_info():
        """应用信息"""
        return jsonify({
            "name": "Flask Comprehensive Example",
            "version": "1.0.0",
            "description": "Flask综合示例应用 - 整合所有工具包功能",
            "features": [
                "用户认证和授权",
                "JWT令牌管理",
                "文章管理系统",
                "文件上传下载",
                "缓存系统",
                "数据库ORM",
                "结构化日志",
                "API响应标准化",
                "异常处理",
                "数据验证"
            ],
            "endpoints": {
                "auth": [
                    "POST /auth/register",
                    "POST /auth/login",
                    "GET  /auth/me",
                    "POST /auth/change-password"
                ],
                "users": [
                    "GET /users",
                    "GET /users/<id>"
                ],
                "articles": [
                    "GET  /articles",
                    "POST /articles",
                    "GET  /articles/<id>",
                    "POST /articles/<id>/publish"
                ],
                "files": [
                    "POST /files/upload",
                    "GET  /files/<id>/download"
                ],
                "cache": [
                    "POST /cache/test"
                ]
            },
            "technologies": [
                "Flask",
                "SQLAlchemy",
                "JWT",
                "Redis/Memory Cache",
                "Structured Logging",
                "Password Hashing",
                "File Upload/Download"
            ]
        })
    
    return app


if __name__ == '__main__':
    app = create_comprehensive_app()
    
    print("=" * 60)
    print("Flask Comprehensive Example")
    print("=" * 60)
    print("综合功能演示:")
    print("  认证系统:")
    print("    POST /auth/register - 用户注册")
    print("    POST /auth/login - 用户登录")
    print("    GET  /auth/me - 获取当前用户")
    print("    POST /auth/change-password - 修改密码")
    print()
    print("  用户管理:")
    print("    GET /users - 获取用户列表（管理员）")
    print("    GET /users/<id> - 获取用户详情")
    print()
    print("  文章系统:")
    print("    GET  /articles - 获取文章列表")
    print("    POST /articles - 创建文章")
    print("    GET  /articles/<id> - 获取文章详情")
    print("    POST /articles/<id>/publish - 发布文章")
    print()
    print("  文件管理:")
    print("    POST /files/upload - 文件上传")
    print("    GET  /files/<id>/download - 文件下载")
    print()
    print("  缓存测试:")
    print("    POST /cache/test - 测试缓存功能")
    print()
    print("  特性:")
    print("    - JWT认证和授权")
    print("    - 角色权限控制")
    print("    - 数据库ORM操作")
    print("    - 文件上传下载")
    print("    - 缓存系统")
    print("    - 结构化日志")
    print("    - 异常处理")
    print("    - 数据验证")
    print("=" * 60)
    
    app.run(
        host='0.0.0.0',
        port=5007,
        debug=True
    )